package com.platform.modules.app.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.platform.annotation.LoginUser;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.service.*;
import com.platform.modules.sys.service.SysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * APP登录授权
 *
 * @author
 */
@Slf4j
@RestController
@RequestMapping("/app/lottery")
@Api(tags = "AppLoginController|九宫格抽奖")
public class AppLotteryController {

    @Autowired
    MallWhitelistService whitelistService;
    @Autowired
    MallUserLotteryLogService userLotteryLogService;
    @Autowired
    JedisUtil jedisUtil;
    @Autowired
    MallUserService userService;
    @Autowired
    MallPrizeService prizeService;
    @Autowired
    MallWinPrizeService winPrizeService;
    @Autowired
    MallGoodsService goodsService;
    @Autowired
    MallActivityService activityService;
    @Autowired
    MallCardSnService cardSnService;


    /**
     * 白名单抽奖
     *
     * @return RestResponse
     */
    @GetMapping("whiteListLot")
    @ApiOperation(value = "白名单抽奖", notes = "白名单抽奖")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "type", value = "白名单", example = "3", dataType = "Integer", defaultValue = "3")
    })
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public RestResponse whiteListLot(@LoginUser MallUserEntity userEntity, @RequestParam("type") Integer type) {
        MallPrizeEntity win = null;
        MallActivityEntity activityEntity = activityService.lambdaQuery()
                .select(MallActivityEntity::getId)
                .eq(MallActivityEntity::getWhitelistType, type)
                .one();
        if (activityEntity == null) {
            return RestResponse.error("活动已结束..");
        }
        // 活动判断
        ActivityStatusResult activityStatus = activityService.getActivityStatus(activityEntity.getId(), null);
        if (activityStatus == null || !activityStatus.getIsStart()) {
            return RestResponse.error("不在活动时间！");
        }
        // 白名单处理
        MallWhitelistEntity whitelistEntity = whitelistService.selectWhitelistEntity(userEntity.getMobile(),type);
        if (whitelistEntity == null) {
            return RestResponse.error("非常抱歉，您暂不符合领取资格");
        }
        //白名单减抽奖次数
        whitelistEntity.setNumber(whitelistEntity.getNumber() - 1);
        whitelistService.updateById(whitelistEntity);
        //排序中奖概率从小到大排序(根据白名单等级)
        List<MallPrizeEntity> entityList = prizeService.list(new LambdaQueryWrapper<MallPrizeEntity>()
                .eq(MallPrizeEntity::getCategoryId, "10")
                .gt(MallPrizeEntity::getNumber, 0)
                .eq(MallPrizeEntity::getActivityId, activityEntity.getId())
                .eq(MallPrizeEntity::getLevel, whitelistEntity.getLevel())
                .orderByAsc(MallPrizeEntity::getProbability));
        if (CollectionUtils.isEmpty(entityList)) {
            throw new BusinessException("奖品被抽完啦，你来晚了！");
        }
        //随机开奖
        double ran1 = Math.random() * 100;
        for (MallPrizeEntity entity : entityList) {
            if (entity.getProbability().compareTo(BigDecimal.valueOf(ran1)) > 0) {
                win = entity;
                break;
            }
        }
        //未抽中则取概率最高奖品（保证必中奖）
        if (null == win) {
            win = entityList.get(entityList.size() - 1);
        }
        //判断库存是否满足 并且减少库存 （利用inndb的行锁实现串行修改）
        if (win.getNumber() > 0) {
            prizeService.PrizeNumberSubtract(win.getPrizeId());
            MallGoodsEntity goods = goodsService.getById(win.getCommodityId());
            goodsService.minusGoodsNumber(goods, 1);
            cardSnService.sendCard(win.getCommodityId(), 1, userEntity);
        } else {
            throw new BusinessException("奖品库存不足！");
        }

        //写入中奖记录
        winPrizeService.setWinPrize(userEntity, win,true);

        //抽奖记录写入数据库
        MallUserLotteryLogEntity userLotteryLogEntity = new MallUserLotteryLogEntity();
        userLotteryLogEntity.setAddTime(new Date());
        userLotteryLogEntity.setCardId(win.getCommodityId());
        userLotteryLogEntity.setCardName(win.getPrizeName());
        userLotteryLogEntity.setCommodityType(win.getType());
        userLotteryLogEntity.setType(type);
        userLotteryLogEntity.setUserId(userEntity.getId());
        if (StringUtils.isNullOrEmpty(userEntity.getUserName())) {
            userLotteryLogEntity.setUserName(userEntity.getNickname());
        } else {
            userLotteryLogEntity.setUserName(userEntity.getNickname() + "(" + userEntity.getUserName() + ")");
        }
        userLotteryLogService.save(userLotteryLogEntity);
        return RestResponse.success().put("data", win);
    }

    /**
     * 九宫格抽奖
     *
     * @return
     */
    @GetMapping("runLottery")
    @ApiOperation(value = "九宫格抽奖", notes = "九宫格抽奖")
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "activityId", value = "活动类型", dataType = "string"),
    })
    public RestResponse runLottery(@LoginUser MallUserEntity userEntity, @RequestParam("activityId")  String activityId) {
        if (userEntity == null) {
            return RestResponse.error("身份信息有误，请稍后重试");
        }
        if (userEntity.getMobile() == null || userEntity.getMobile().length() < 7) {
            return RestResponse.error("请先绑定手机号");
        }
        MallActivityEntity activity = activityService.getById(activityId);
        MallWhitelistEntity entity = whitelistService.selectWhitelistEntity(userEntity.getMobile(),activity.getWhitelistType());
        //抽奖次数次数处理
        if (!whitelistService.reduceByPhone(userEntity.getMobile(), 1, entity.getType())) {
            return RestResponse.error("可用抽奖次数不足");
        }
        // 抽奖
        return RestResponse.success().put("data", prizeService.runLottery(userEntity, activity.getWhitelistType().toString(), entity.getLevel()));

    }

    /**
     * 获取九宫格奖品列表
     *
     * @return 卡券列表
     */
    @GetMapping("/getPrizeList")
    @ApiOperation(value = "获取九宫格奖品列表", notes = "获取九宫格奖品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
    })
    public RestResponse getPrizeList() {
        //通过组别获取卡卷列表 排序根据卡券排序从小到大
        List<MallPrizeEntity> cardEntityList = prizeService.list(new LambdaQueryWrapper<MallPrizeEntity>()
                .eq(MallPrizeEntity::getCategoryId, "9")
                .orderByAsc(MallPrizeEntity::getSort)
                .last("limit 0,8"));
        if (cardEntityList.size() < 8) {
            // 奖品不足使用 谢谢惠顾补上
            for (int i = cardEntityList.size(); i < 8; i++) {
                MallPrizeEntity entity = new MallPrizeEntity();
                entity.setPrizeName("谢谢参与");
                entity.setType(-1);
                entity.setImage("https://lybank-1302786294.cos.ap-guangzhou.myqcloud.com/images/20210914/3f002d97b0a6425983e58248aaa06aa0.png");
                cardEntityList.add(entity);
            }
        }
        return RestResponse.success().put("data", cardEntityList);
    }

    /**
     * 九宫格 获取最新中奖信息
     *
     * @return RestResponse
     */
    @GetMapping("getCurrentWinPrizeInfo")
    @ApiOperation(value = "九宫格 获取最新中奖信息", notes = "九宫格 获取最新中奖信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
    })
    public RestResponse getCurrentWinPrizeInfo() {
        return RestResponse.success().put("data", jedisUtil.getList("WinPrizeList")
                .stream().map(x -> JSONObject.parseObject(x)).collect(Collectors.toList()));
    }

    /**
     * 九宫格 获取用户中奖记录
     *
     * @return RestResponse
     */
    @GetMapping("getUserWinPrizeList")
    @ApiOperation(value = "九宫格 获取用户中奖记录", notes = "九宫格 获取用户中奖记录")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "page", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int")
    })
    public RestResponse getUserWinPrizeList(@LoginUser MallUserEntity userEntity, @RequestParam Map<String, Object> params) {
        params.put("userId", userEntity.getId());
        return RestResponse.success().put("data", winPrizeService.queryPage(params));
    }

    /**
     * 九宫格 中奖详细信息
     *
     * @return RestResponse
     */
    @GetMapping("getWinPrizeGoodsInfo")
    @ApiOperation(value = "九宫格 查看中奖商品详细信息", notes = "九宫格 查看中奖商品详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "id", value = "中奖列表的数据ID", required = true, dataType = "string")
    })
    public RestResponse getWinPrizeGoodsInfo(@RequestParam String id) {
        MallWinPrizeEntity entity = winPrizeService.getOne(new QueryWrapper<MallWinPrizeEntity>()
                .select("id", "type", "commodity_Id", "commodity_Name", "commodity_Img", "use_Integral", "add_Time")
                .eq("id", id));
        Map<String, Object> commodity = new HashMap<>(4);
        return RestResponse.success().put("data", entity);
    }

}
